package com.example.onlinemonitoring.comCenter;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.HexUtil;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.model.Mxcwsensor;
import com.example.onlinemonitoring.model.Mxcwhistory;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.serviceImpl.MxcwsensorServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.context.annotation.Scope;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
/*母线测温
*/
@Service("mxcwCom")
@Scope("prototype")
public class MxcwCom extends CommPortManager {
        @Autowired
        private MxcwsensorServiceImpl mxcwsensorServiceImpl;
        int cmd = 1;
        @Override
        public void receiveData(String str) {
            try {
                str = str.toUpperCase();
                setText(str);
                String addrstr = str.substring(0, 2);
                Integer addr = parseHex4(addrstr);

                if (!"03".equals(str.substring(2, 4)))
                return;

                reSend[addrindex] = 0;
                addrindex++;
                Integer startIndex = 6;//数据起始位置
                setText("设备返回数据： 站点号：" + ad.getStationid() + " 设备组：" + ad.getDevicegroup() + " 设备地址：" + addr);
                float li=0,lvalue=0,noise=0,temperature=0;
                int channelstatus=0;

                Mxcwsensor mxcwsensor = new Mxcwsensor();
                mxcwsensor.setStationid(ad.getStationid());
                mxcwsensor.setDeviceaddr(addr);
                mxcwsensor.setDevicegroup(ad.getDevicegroup());
                MyResult<Mxcwsensor> res = mxcwsensorServiceImpl.getList(mxcwsensor);
                
                if(cmd==1)
                {
                    for (int i = 0; i < 60; i++) {
                    temperature = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();

                    setText("温度：" + temperature + "℃ "  +"监测点:" + (i+1) );

                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1) + " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;

                    mxcwsensor.setPointaddr(record.getPointaddr());
                    mxcwsensor.setLasttemper(temperature);
                    mxcwsensor.setLastdatatime(new Date());
                    AddAndUpdate(record,mxcwsensor);
                    }
                    
                    cmd = 3;
                    if(res.getCount()>60)
                        cmd = 2;
                }
                else if(cmd==2)
                {
                    for (int i = 60; i < res.getCount(); i++) {
                    temperature = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();

                    setText("温度：" + temperature + "℃ "  +"监测点:" + (i+1)  );

                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1)+ " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;

                    mxcwsensor.setPointaddr(record.getPointaddr());
                    mxcwsensor.setLasttemper(temperature);
                    mxcwsensor.setLastdatatime(new Date());
                    AddAndUpdate(record,mxcwsensor);
                    }
                    cmd = 3;
                }
                else if(cmd==3)
                {
                    for (int i = 0; i < 60; i++) {
                    li = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();

                    setText("光强：" + li + " "  +"监测点:" + (i+1)  );


                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1) + " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;

                    mxcwsensor.setPointaddr(record.getPointaddr());
                    mxcwsensor.setLastli(li);
                    mxcwsensor.setLastcommunicationstatus(0);
                    mxcwsensor.setLastdatatime(new Date());
                    if ( mxcwsensorServiceImpl.Update(mxcwsensor, false) == 0) {
                        setText("更新实时数据失败，请检查数据库连接");
                    }
                    }
                    cmd = 5;
                    if(res.getCount()>60)
                        cmd = 4;
                }
                else if(cmd==4)
                {
                    for (int i = 60; i < res.getCount(); i++) {
                    li = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();

                     setText("光强：" + li + " "  +"监测点:" + (i+1)  );

                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1) + " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;

                    mxcwsensor.setPointaddr(record.getPointaddr());
                     mxcwsensor.setLastli(li);
                    mxcwsensor.setLastcommunicationstatus(0);
                    mxcwsensor.setLastdatatime(new Date());
                    if ( mxcwsensorServiceImpl.Update(mxcwsensor, false) == 0) {
                        setText("更新实时数据失败，请检查数据库连接");
                    }  
                    }
                    cmd = 5;
                }
                else if(cmd==5)
                {
                    for (int i = 0; i < 60; i++) {
                    noise = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();
                    setText("干扰：" + noise + "dB "  +"监测点:" + (i+1)  );
                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1) + " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;
                    mxcwsensor.setPointaddr(record.getPointaddr());
                    mxcwsensor.setLastnoise(noise);
                    mxcwsensor.setLastcommunicationstatus(0);
                    mxcwsensor.setLastdatatime(new Date());
                    if ( mxcwsensorServiceImpl.Update(mxcwsensor, false) == 0) {
                        setText("更新实时数据失败，请检查数据库连接");
                    }
                    }
                    cmd = 1;
                    if(res.getCount()>60)
                        cmd = 6;
                }
                else if(cmd==6)
                {
                    for (int i = 60; i < res.getCount(); i++) {
                    noise = IEEE754Utils.strbytesToSingleTurn(str.substring(startIndex, startIndex+=8)).floatValue();
                    setText("干扰：" + noise + "dB "   +"监测点:" + (i+1) );
                    //查询对象
                    Mxcwsensor record = res.getData().get(i);
                    if (record == null) {
                        setText("当前数据库无监测点：设备地址" + addr + "的监测点" + (i+1) + " ！ 请先添加该监测点！");
                        return;
                    }
                    if(record.getInuse()==0)
                    return;
                    mxcwsensor.setPointaddr(record.getPointaddr());
                    mxcwsensor.setLastnoise(noise);
                    mxcwsensor.setLastcommunicationstatus(0);
                    mxcwsensor.setLastdatatime(new Date());
                    if ( mxcwsensorServiceImpl.Update(mxcwsensor, false) == 0) {
                        setText("更新实时数据失败，请检查数据库连接");
                    }
                    }
                    cmd = 1;
                    addrindex++;
                }              
                } catch (Exception ex) {
                    ex.printStackTrace();
                    setText("从设备返回的数据有误！请检查串口！");
                }
        }

        @Transactional
        private void AddAndUpdate(Mxcwsensor record,Mxcwsensor mxcw) {
            if (record.getTemperalarmvalue() == null ||
                record.getTemperalarmrelievevalue() == null ||
                record.getTemperwarnvalue() == null ||
                record.getTemperwarnrelievevalue() == null //||
                // record.getLialarmvalue() == null ||
                // record.getLialarmrelievevalue() == null ||
                // record.getLiwarnvalue() == null ||
                // record.getLiwarnrelievevalue() == null||
                // record.getLvaluealarmvalue() == null ||
                // record.getLvaluealarmrelievevalue() == null ||
                // record.getLvaluewarnvalue() == null ||
                // record.getLvaluewarnrelievevalue() == null ||
                // record.getNoisealarmvalue() == null ||
                // record.getNoisealarmrelievevalue() == null ||
                // record.getNoisewarnvalue() == null ||
                // record.getNoisewarnrelievevalue() == null 
        ) {
            setText("设备地址" + record.getDeviceaddr() + " 未设置报警值！");
            return;
        }
            int alarmLevel = 0;// 报警等级
            String alarmMessage = "";// 报警消息
            List<Integer> array = new ArrayList<>();
            mxcw.setLasttemperstatus(
                GetAlarmStatus(isnull(mxcw.getLasttemper()), isnull(record.getTemperalarmvalue()),
                        isnull(record.getTemperalarmrelievevalue()), isnull(record.getTemperwarnvalue()),
                        isnull(record.getTemperwarnrelievevalue()),
                        isnull(record.getLasttemperstatus()), true, "温度",record.getDevicegroup(), record.getDeviceaddr(),
                        record.getPointname(),record.getPointaddr()));
            alarmMessage += GetAlarmMessage(mxcw.getLasttemperstatus(), "温度");
            array.add(mxcw.getLasttemperstatus());
            // mxcw.setLastlistatus(
            //     GetAlarmStatus(isnull(mxcw.getLastli()), isnull(record.getLialarmvalue()),
            //             isnull(record.getLialarmrelievevalue()), isnull(record.getLiwarnvalue()),
            //             isnull(record.getLiwarnrelievevalue()),
            //             isnull(mxcw.getLastlistatus()), true, "光强",record.getDevicegroup(),  record.getDeviceaddr(),
            //             record.getPointname(),record.getPointaddr()));
            // alarmMessage += GetAlarmMessage(mxcw.getLastlistatus(), "光强");
            // array.add(mxcw.getLastlistatus());
            // mxcw.setLastlvaluestatus(
            //     GetAlarmStatus(isnull(mxcw.getLastlvalue()), isnull(record.getLvaluealarmvalue()),
            //             isnull(record.getLvaluealarmrelievevalue()), isnull(record.getLvaluewarnvalue()),
            //             isnull(record.getLvaluewarnrelievevalue()),
            //             isnull(mxcw.getLastlvaluestatus()), true, "光值",record.getDevicegroup(),  record.getDeviceaddr(),
            //             record.getPointname(),record.getPointaddr()));
            // alarmMessage += GetAlarmMessage(mxcw.getLastlvaluestatus(), "光值");
            // array.add(mxcw.getLastlvaluestatus());
            // mxcw.setLastnoisestatus(
            //     GetAlarmStatus(isnull(mxcw.getLastnoise()), isnull(record.getNoisealarmvalue()),
            //             isnull(record.getNoisealarmrelievevalue()), isnull(record.getLvaluewarnvalue()),
            //             isnull(record.getNoisewarnrelievevalue()),
            //             isnull(mxcw.getLastnoisestatus()), true, "干扰",record.getDevicegroup(),  record.getDeviceaddr(),
            //             record.getPointname(),record.getPointaddr()));
            // alarmMessage += GetAlarmMessage(mxcw.getLastnoisestatus(), "干扰");
            // array.add(mxcw.getLastnoisestatus());

           // array.add(mxcw.getLastchannelstatus());
            alarmLevel = HexUtil.MAX(array);
            // if(mxcw.getLastchannelstatus()!=0)
            // {
            //     alarmMessage +=alarmMessage +  "，没有信号";
            // }
            // else{
            //     alarmMessage +=alarmMessage +  "信号正常";
            // }
        
            mxcw.setLastalarmlevel(alarmLevel);
            mxcw.setLastalarmmessage(alarmMessage);
            mxcw.setLastcommunicationstatus(0);
            mxcw.setLastdatatime(new Date());
            mxcw.setLasthisdatatime(addHistory(record));
            if ( mxcwsensorServiceImpl.Update(mxcw, false) == 0) {
                setText("更新实时数据失败，请检查数据库连接");
            }
        }
        private Date addHistory(Mxcwsensor sensor) {
            if (sensor != null) {
                if (sensor.getLasthisdatatime() == null) {
                    add(sensor);
                    return new Date();
                } else {
                    long lasttime = 0;
                    long nowtime = 0;
                    try {
                        lasttime = HexUtil.todate(sensor.getLasthisdatatime()).getTime();
                        nowtime = HexUtil.todate(new Date()).getTime();
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    int timersp = 60000;
                    if (sensor.getLastalarmlevel() != 0) {
                        timersp = ad.getHisalarmtimersp()*1000;
                    } else {
                        timersp = ad.getHistimersp()*1000;
                    }
                    if (lasttime + timersp < nowtime) {
                        add(sensor);
                        return new Date();
                    }
                }
            }
            return null;
        }

        private void add(Mxcwsensor sensor) {
            Mxcwhistory his = new Mxcwhistory();
            his.setDeviceaddr(sensor.getDeviceaddr());
            his.setDevicegroup(sensor.getDevicegroup());
            his.setAlarmlevel(sensor.getLastalarmlevel());
            his.setAlarmmessage(sensor.getLastalarmmessage());
            his.setDatatime(sensor.getLastdatatime());
            his.setPointname(sensor.getPointname());
            his.setPointaddr(sensor.getPointaddr());
            his.setStationid(sensor.getStationid());
            his.setCommunicationstatus(sensor.getLastcommunicationstatus());
            
            his.setTemper(sensor.getLasttemper());
            his.setLi(sensor.getLastli());
           // his.setLvalue(sensor.getLastlvalue());
            his.setNoise(sensor.getLastnoise());
            his.setTemperstatus(sensor.getLasttemperstatus());
            his.setListatus(sensor.getLastlistatus());
            //his.setLvaluestatus(sensor.getLastlvaluestatus());
            his.setNoisestatus(sensor.getLastnoisestatus());
            //his.setChannelstatus(sensor.getLastchannelstatus());
            mxcwsensorServiceImpl.Add(his);
        }


        @Async("threadPool")
        public void startSendThread(Appdevice Appdevice) throws Exception {
            checkType = "crc16";
            issend.put(Thread.currentThread().getId(), true);
            String cstr = "";
            String cmdtype = "";
            String nametype = "";
            int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
            while (issend.get(Thread.currentThread().getId()) != null) {
                if (addrindex > Appdevice.getAddrmax() || addrindex < Appdevice.getAddrmin())
                    addrindex = Appdevice.getAddrmin();

                    if(cmd==1)
                    {
                        cstr =  String.format("%02X", addrindex) + "031b580078";//温度
                    }
                    else if(cmd==2)
                    {
                         cstr =  String.format("%02X", addrindex) + "031bD00078";//温度
                    }
                    else if(cmd==3)
                    {
                        cstr =  String.format("%02X", addrindex) + "0323280078";//光强
                    }
                    else if(cmd==4)
                    {
                        cstr =  String.format("%02X", addrindex) + "0323A00078";//光强
                    }
                    else if(cmd==5)
                    {
                        cstr =  String.format("%02X", addrindex) + "0329040078";//干扰
                    }
                    else if(cmd==6)
                    {
                        cstr =  String.format("%02X", addrindex) + "03297C0078";//干扰
                    }
                    cstr = cstr + CRC16.calcCrc16(cstr);
                try {
                    Send(cstr);
                } catch (Exception EX) {
                     setText(EX.toString());
                }
                setText("向" + Appdevice.getName() + "设备发送指令" + cstr);
                reSend[addrindex]++;
                if (reSend[addrindex] > 3) {
                mxcwsensorServiceImpl.UpdateStatus(ad, addrindex,1);
                reSend[addrindex] = 0;
                addrindex++;
                }
                Thread.sleep(timersp);
            }
        }
        public static float parseHex88(String num) {
            int ret = Integer.parseInt(num, 16);
            if (num.length() == 2) {
                return ret;
            } else if (num.length() == 4) {
                ret = ((ret & 0x8000) > 0) ? (ret - 0x10000) : (ret);
                return ret;
            } else {
                throw new NumberFormatException("Wrong length: " + num.length() + ", must be 4.");
            }
        }
        // @Async("threadPool")
        // public void startReceiveThread(){
        //     isrecv.put(Thread.currentThread().getId(), true);
        //     while (isrecv.get(Thread.currentThread().getId()) != null) {
        //         //这里根据实际协议替换,解析方法recvCrc16;recvSum();
        //         recv();
        //         try {
        //             Thread.sleep(interval);
        //         } catch (InterruptedException e) {
        //             e.printStackTrace();
        //         }
        //     }
        // }
}
